home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 426-450 / disk_436 / keymacro / null-handler.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  5KB  |  202 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1990 by MXM
  4.  *
  5.  *    Name .....: Null-Handler.c
  6.  *    Created ..: Saturday 31-Mar-90 13:47
  7.  *    Revision .: 0
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    15-Apr-90       Olsen           Ported to Aztec 'C' 5.0
  12.  *    07-Jan-90       Olsen           Created this file!
  13.  *
  14.  *    Skeleton    handler    code   by   Phillip   Lindsay   (C)   1986
  15.  *    Commodore-Amiga,  Inc.  You may freely distribute this source and
  16.  *    use  it for Amiga Development, as long as the Copyright notice is
  17.  *    left intact.
  18.  *
  19.  ****************************************************************************
  20.  *
  21.  *    This  is  an  example how a 'real' NIL:  handler could look like.
  22.  *    It  is very loosely based on the 'my-handler' source code written
  23.  *    by Phillip Lindsay.  Since I have no access to the source code of
  24.  *    the  original  Null-Handler  I  rewrote it using Lattice 'C' 5.04
  25.  *    which  resulted  in  a very small executable file (actually about
  26.  *    568 bytes long, about 340 bytes less than the original handler).
  27.  *           Three weeks later I thought "well, why not try to bring it
  28.  *    back to Aztec 'C'?".  And that's what I did.  I can't believe it,
  29.  *    Aztec 'C' 5.0 does a brilliant job on the program:  it's actually
  30.  *    124 bytes smaller than the Lattice version.
  31.  *
  32.  * $Revision Header ********************************************************/
  33.  
  34.     /* Main includes. */
  35.  
  36. #include <libraries/filehandler.h>
  37. #include <libraries/dosextens.h>
  38. #include <exec/execbase.h>
  39.  
  40. #include <pragma/exec_lib.h>
  41.  
  42. /*#include <functions.h>*/
  43.  
  44.     /* Prototypes for this module. */
  45.  
  46. LONG            HandlerEntry(VOID);
  47. VOID            ReturnPacket(struct DosPacket *Packet,ULONG Res1,ULONG Res2,struct Process *HandlerProc);
  48. struct DosPacket *    WaitPacket(struct Process *HandlerProc);
  49.  
  50.     /* Some magic pragmas. */
  51.  
  52. #pragma regcall(ReturnPacket(a0,d0,d1,a1))
  53. #pragma regcall(WaitPacket(a0))
  54.  
  55.     /* Global pointer to ExecBase. */
  56.  
  57. struct ExecBase        *SysBase;
  58.  
  59.     /* HandlerEntry():
  60.      *
  61.      *    The entry point for this handler.
  62.      */
  63.  
  64. LONG
  65. HandlerEntry()
  66. {
  67.     struct Process *HandlerProc;
  68.  
  69.         /* Set the ExecBase pointer. */
  70.  
  71.     SysBase = (struct ExecBase *)(*(LONG *)4);
  72.  
  73.         /* Get a pointer to the process structure of the
  74.          * handler.
  75.          */
  76.  
  77.     HandlerProc = (struct Process *)SysBase -> ThisTask;
  78.  
  79.         /* If not called from CLI (you shouldn't do that)
  80.          * we'll start up as a DOS-handler.
  81.          */
  82.  
  83.     if(!HandlerProc -> pr_CLI)
  84.     {
  85.         struct DosPacket    *NullPacket;
  86.         struct DeviceNode    *NullNode;
  87.  
  88.             /* Wait for startup packet (we aren't a
  89.              * BCPL module).
  90.              */
  91.  
  92.         NullPacket = WaitPacket(HandlerProc);
  93.  
  94.             /* Get pointer to handler device node. */
  95.  
  96.         NullNode = (struct DeviceNode *)BADDR(NullPacket -> dp_Arg3);
  97.  
  98.             /* Install handler task ID -> we're running. */
  99.  
  100.         NullNode -> dn_Task = &HandlerProc -> pr_MsgPort;
  101.  
  102.             /* Return the startup packet to DOS. */
  103.  
  104.         ReturnPacket(NullPacket,DOSTRUE,NullPacket -> dp_Res2,HandlerProc);
  105.  
  106.             /* Run forever - or until somebody lets us die. */
  107.  
  108.         for(;;)
  109.         {
  110.                 /* Wait for a packet. */
  111.  
  112.             NullPacket = WaitPacket(HandlerProc);
  113.  
  114.                 /* Check the type. */
  115.  
  116.             switch(NullPacket -> dp_Type)
  117.             {
  118.                 case ACTION_FINDINPUT:
  119.                 case ACTION_FINDOUTPUT:
  120.                 case ACTION_FINDUPDATE:    
  121.                 case ACTION_END:    ReturnPacket(NullPacket,DOSTRUE,0,HandlerProc);
  122.                             break;
  123.  
  124.                 case ACTION_WRITE:    ReturnPacket(NullPacket,NullPacket -> dp_Arg3,0,HandlerProc);
  125.                             break;
  126.  
  127.                 case ACTION_READ:    ReturnPacket(NullPacket,0,0,HandlerProc);
  128.                             break;
  129.  
  130.                 case ACTION_DIE:    ReturnPacket(NullPacket,DOSTRUE,0,HandlerProc);
  131.                             goto FallOff;
  132.  
  133.                 default:        ReturnPacket(NullPacket,DOSFALSE,ERROR_ACTION_NOT_KNOWN,HandlerProc);
  134.                             break;
  135.             }
  136.         }
  137.  
  138.             /* Okay, we're done, zero the task ID field
  139.              * and fall through.
  140.              */
  141.     
  142. FallOff:    NullNode -> dn_Task = NULL;
  143.     }
  144. }
  145.  
  146.     /* ReturnPacket():
  147.      *
  148.      *    Returns a packet to DOS.
  149.      */
  150.  
  151. VOID
  152. ReturnPacket(struct DosPacket *Packet,ULONG Res1,ULONG Res2,struct Process *HandlerProc)
  153. {
  154.     struct MsgPort *ReplyPort;
  155.  
  156.         /* Remember origin port. */
  157.  
  158.     ReplyPort = Packet -> dp_Port;
  159.  
  160.         /* Fill in the result fields. */
  161.  
  162.     Packet -> dp_Res1 = Res1;
  163.     Packet -> dp_Res2 = Res2;
  164.  
  165.         /* Install our task ID. */
  166.  
  167.     Packet -> dp_Port = &HandlerProc -> pr_MsgPort;
  168.  
  169.         /* Initialize the packet node head. */
  170.  
  171.     Packet -> dp_Link -> mn_Node . ln_Name    = (char *)Packet;
  172.     Packet -> dp_Link -> mn_Node . ln_Succ    = NULL;
  173.     Packet -> dp_Link -> mn_Node . ln_Pred    = NULL;
  174.  
  175.         /* Return the packet to the sender. */
  176.  
  177.     PutMsg(ReplyPort,Packet -> dp_Link);
  178. }
  179.  
  180.     /* WaitPacket():
  181.      *
  182.      *    Wait for a DOS packet.
  183.      */
  184.  
  185. struct DosPacket *
  186. WaitPacket(struct Process *HandlerProc)
  187. {
  188.     struct Message *DOSMsg;
  189.  
  190.         /* Wait at the port... */
  191.  
  192.     WaitPort(&HandlerProc -> pr_MsgPort);
  193.  
  194.         /* Get the packet. */
  195.  
  196.     DOSMsg = (struct Message *)GetMsg(&HandlerProc -> pr_MsgPort);
  197.  
  198.         /* Return a pointer to its head. */
  199.  
  200.     return((struct DosPacket *)DOSMsg -> mn_Node . ln_Name);
  201. }
  202.